using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.Events;

public class WeaponControllerBase : MonoBehaviour
{
    public UnityEvent<Vector2> OnPerformAttack;

    [Header("检测设置")]
    [SerializeField] protected float checkRadius = 5f;  // 武器检测敌人的范围
    [SerializeField] protected LayerMask whatIsEnemy;
    [SerializeField] protected float checkInterval = 0.1f;  // 检测间隔,避免每帧计算
    private Transform _parent;

    [Header("武器冷却设置")]
    [SerializeField] protected float cooldownDuration;
    private protected float lastUseTime;
    
    protected Collider2D[] checkedTargets;
    protected bool canAiming = true;
    protected float lastCheckTime;
    protected Transform currentTarget;  // 缓存当前目标，减少重复计算
    protected Vector3 originalLocalScale;
    protected Coroutine weaponAttackCo;
    private bool _isAutoAttack;
    private Player _player => Player.Instance;
    private bool _isStopContorll;
    protected virtual void Awake()
    {
        originalLocalScale = transform.localScale;
        lastUseTime -= cooldownDuration;
        
    }
    private void OnEnable()
    {
        EventCenter.AddEventListener<ViewType>(EventName.SwitchViewState, SwitchAttackMode);
        EventCenter.AddEventListener(EventName.PlayerDead, SetWeaponStopControll);
        SwitchAttackMode(_player.CurrentViewType);
        _isStopContorll = false;
    }
    private void OnDisable()
    {
        EventCenter.RemoveEventListener<ViewType>(EventName.SwitchViewState, SwitchAttackMode);
        EventCenter.RemoveEventListener(EventName.PlayerDead, SetWeaponStopControll);
    }
    private void Start()
    {
        _parent = transform.parent;
    }
    protected virtual void Update()
    {
        if (_isStopContorll)
            return;
        if (_isAutoAttack)
            AutoAttack();
        else
            ManualAttack();
    }
    private void SetWeaponStopControll()
    {
        _isStopContorll = true;
    }
    /// <summary>
    /// 视角转换事件
    /// </summary>
    /// <param name="viewType"></param>
    private void SwitchAttackMode(ViewType viewType)
    {
        if (viewType == ViewType.Side)
            _isAutoAttack = true;
        else if (viewType == ViewType.Top)
            _isAutoAttack = false;
    }

    /// <summary>
    /// 手动攻击
    /// </summary>
    private void ManualAttack()
    {
        // if (_player.PlayerInput.Player.Attack.IsPressed() == false || IsCooldown())
        //     return;
        if (currentTarget == null && _player.MoveInput.x != 0)
        {
            Vector2 horizontalDir = new(_player.MoveInput.x, 0);
            WeaponIdle(horizontalDir);
        }
        if (_player.PlayerInput.Player.Attack.WasPressedThisFrame() == false)
            return;
        Vector3 targetPos = GetMouseWorldPosition();
        WeaponAiming(targetPos);

        Vector2 targetMouseLocalDirection = GetTargetObjectLocalDirection(targetPos, _parent);
        WeaponPeformAttack(targetMouseLocalDirection);
    }

    /// <summary>
    /// 自动攻击
    /// </summary>
    private void AutoAttack()
    {
        // 间隔检测目标，避免每帧检测
        if (Time.time - lastCheckTime >= checkInterval)
        {
            currentTarget = GetAttackTarget();
            lastCheckTime = Time.time;
        }

        if (currentTarget == null && _player.MoveInput.x != 0)
        {
            Vector2 horizontalDir = new(_player.MoveInput.x, 0);
            WeaponIdle(horizontalDir);
        }

        if (currentTarget != null)
        {
            Vector2 enemyPos = currentTarget.position;

            if (canAiming)
                WeaponAiming(enemyPos);

            if (IsCooldown() == false)
            {
                Vector2 targetEnemyLocalDirection = GetTargetObjectLocalDirection(enemyPos, _parent);
                WeaponPeformAttack(targetEnemyLocalDirection);
            }
        }
    }
    /// <summary>
    /// 得到鼠标的世界位置
    /// </summary>
    /// <returns></returns>
    private Vector3 GetMouseWorldPosition()
    {
        Vector3 screenPos = new(Input.mousePosition.x, Input.mousePosition.y, Camera.main.nearClipPlane);

        // 注意：2D场景中相机通常是正交相机（Orthographic），转换后z轴可能不为0，需要处理
        Vector3 worldPos = Camera.main.ScreenToWorldPoint(screenPos);

        // 3. 忽略Z轴（2D场景中物体通常在z=0平面）
        worldPos.z = 0;

        return worldPos;
    }

    protected virtual void WeaponPeformAttack(Vector2 attackDirection)
    {
        SetCooldown();
        OnPerformAttack?.Invoke(attackDirection);
    }

    /// <summary>
    /// 武器在进行攻击时的瞄准
    /// </summary>
    /// <param name="targetDir"></param>
    private void WeaponAiming(Vector3 targetPos)
    {
        // 计算目标方向
        Vector2 direction = (targetPos - transform.position).normalized;

        float targetAngle = Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg;

        //判断当前方向是否在x轴左侧，如果在左侧，则需要翻转武器
        bool isShouldFlip = direction.x < 0;
        if (isShouldFlip)
        {
            transform.localScale = new Vector3(-originalLocalScale.x, originalLocalScale.y, originalLocalScale.z);
            targetAngle -= 180;
        }
        else
            transform.localScale = originalLocalScale;

        transform.localRotation = Quaternion.Euler(0, 0, targetAngle);
    }

    /// <summary>
    /// 武器在未进行攻击时的瞄准
    /// </summary>
    /// <param name="targetDir"></param>
    private void WeaponIdle(Vector2 targetDir)
    {
        targetDir.Normalize();
        float targetAngle = Mathf.Atan2(targetDir.y, targetDir.x) * Mathf.Rad2Deg;
        //判断当前方向是否在x轴左侧，如果在左侧，则需要翻转武器
        bool isShouldFlip = targetDir.x < 0;
        if (isShouldFlip)
        {
            transform.localScale = new Vector3(-originalLocalScale.x, originalLocalScale.y, originalLocalScale.z);
            targetAngle -= 180;
        }
        else
            transform.localScale = originalLocalScale;

        transform.localRotation = Quaternion.Euler(0, 0, targetAngle);
    }

    /// <summary>
    /// 范围检测，linq查询得到攻击目标
    /// </summary>
    public Transform GetAttackTarget()
    {
        // 检测范围内的敌人碰撞体
        checkedTargets = Physics2D.OverlapCircleAll(transform.position, checkRadius, whatIsEnemy);

        if (checkedTargets == null || checkedTargets.Length == 0)
            return null;

        return checkedTargets.OrderBy(t => Vector2.Distance(transform.position, t.transform.position)).First().transform;
    }

    /// <summary>
    /// 传入目标对象的世界位置和目标转换的父级，返回目标对象的局部位置相对于自身局部位置的方向
    /// </summary>
    /// <param name="targetPos"></param>
    /// <returns></returns>
    public Vector2 GetTargetObjectLocalDirection(Vector2 targetPos, Transform parent)
    {
        //敌人相对于武器挂载点的局部坐标转换
        Vector3 enemyLocalPos = GetTargetEnemyLocalPosition(targetPos, parent);
        //武器相对于敌人的局部方向向量
        Vector2 localDirection = (enemyLocalPos - transform.localPosition).normalized;
        return localDirection;
    }

    /// <summary>
    /// 传入目标对象的世界位置和目标转换的父级，返回目标对象相对于父级的局部位置
    /// </summary>
    /// <param name="targetPos"></param>
    /// <param name="parent"></param>
    /// <returns></returns>
    public Vector2 GetTargetEnemyLocalPosition(Vector2 targetPos, Transform parent) => parent.InverseTransformPoint(targetPos);
    
    public void SetCooldown() => lastUseTime = Time.time;

    public bool IsCooldown() => Time.time - lastUseTime < cooldownDuration;
    
    public virtual void OnDrawGizmos()
    {
        Gizmos.color = Color.red;
        Gizmos.DrawWireSphere(transform.position, checkRadius);
    }
    
}
